﻿/* 
 * File:   alspi.h
 * Author: aple
 */

#ifndef SPI_SW_HALL_H
#define SPI_SW_HALL_H

#include "stdint.h"

#ifdef __cplusplus
extern "C"
{
#endif

  typedef struct
  {
    uint8_t speed;
    uint8_t bits; //0-31 位数=bits+1
  } spi_info_type;

  typedef const struct
  {
    void (*cs_out_high)(void);
    void (*cs_out_low)(void);

    void (*sck_out_high)(void);
    void (*sck_out_low)(void);

    void (*mosi_out_high)(void);
    void (*mosi_out_low)(void);

    uint8_t (*miso_st_get)(void);

    void (*insert_clks)(void); //低速模式时时钟时钟宽度

    spi_info_type *info;
  } spi_cfg_type;

  void sw_spi_init(spi_cfg_type *spi);
  
  //MSB
  uint32_t sw_spi_rw(spi_cfg_type *spi, uint32_t wdata);
  //LSB
  uint32_t sw_lsbspi_rw(spi_cfg_type *spi, uint32_t wdata);

  
  void sw_spi_cs(spi_cfg_type *spi, uint8_t cs);
  void sw_spi_speed(spi_cfg_type *spi, uint8_t high1_or_low0);

  //qpi
  /* 位输出时序
    *  msb_msk计算 -> sck_low()->io_out->sck_high  |
    *      <---------------------------------------|
    */

    typedef const struct
    {
        void (*cs_out_high)(void);
        void (*cs_out_low)(void);

        void (*sck_out_high)(void); //从机采样边沿，拉高前可根据主频加入一定量的NOP，拉高后需保持一定NOP,如果芯片速度不高，函数调用超过30ns可以不用加NOP
        void (*sck_out_low)(void);

        void (*io0_out_high)(void); 
        void (*io0_out_low)(void);  
        uint8_t (*io0_st_get)(void);

        void (*io1_out_high)(void);
        void (*io1_out_low)(void);
        uint8_t (*io1_st_get)(void);

        void (*io2_out_high)(void);
        void (*io2_out_low)(void);
        uint8_t (*io2_st_get)(void);

        void (*io3_out_high)(void);
        void (*io3_out_low)(void);
        uint8_t (*io3_st_get)(void);

        void (*insert_clks)(void); //低速模式时时钟时钟宽度

        spi_info_type *info;  // bit = bits*4
    } qpi_cfg_type;
  
    //管脚方向外部切换
    void sw_qpi_write(qpi_cfg_type *qpi, uint32_t wdata);
    uint32_t sw_qpi_read(qpi_cfg_type *qpi);
    
#ifdef __cplusplus
}
#endif

#endif /* SPI_SW_HALL_H */
